package cn.com.wxd.common.file;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.com.wxd.service.attach.AttachConfEntity;
import cn.com.wxd.common.CharUtil;
import cn.com.wxd.common.DateUtil;
import cn.com.wxd.service.attach.entity.AttachInfo;

/**
 * Title:文件上传
 * Description:apach upload文件上传
 * 
 * Company: Amumu管理平台
 * Copyright: Copyright (c) 2015
 * All right reserved.
 * Created time: 2015-12-28 下午6:08:10
 * 文件上传
 * @author WangXuDong
 * @version 1.0
 */
public class FileUpload {
	private static final Logger log = LoggerFactory.getLogger(FileUpload.class);
	/**
	 * 上传一个文件
	 * @param request HttpServletRequest
	 * @param path 上传的路径 绝对路径或者相对路径，
	 * @param catchPath 缓存文件路径 绝对路径或者相对路径
	 * @param isRecordBd 是否纪录到数据库
	 * @return list 上传文件后，上传的所有文件信息列表
	 * @throws IOException,Exception 
	 */
	public List<AttachInfo> fileUpload(HttpServletRequest request, String path,
									   String bufferPath, boolean isRecordBd, AttachConfEntity ace) throws Exception{

		List<AttachInfo> returnlist = new ArrayList<>();
		try {
			request.setCharacterEncoding("UTF-8");
		} catch (UnsupportedEncodingException e) {
			log.error(e.getMessage(),e);
		}

		boolean createb = true;
		// 创建文件夹
		File dirFile = new File(path);
		if (!dirFile.exists()) {
			createb = dirFile.mkdirs();
		}
		// 创建临时文件夹
		File dirTempFile = new File(bufferPath);
		if (!dirTempFile.exists()) {
			createb = dirTempFile.mkdirs();
		}
		if(!createb){
			throw new IOException("Directory Create Failure,because " + path +"--" + bufferPath);
		}

		DiskFileItemFactory factory = new DiskFileItemFactory();
		factory.setSizeThreshold(5 * 1024 * 1024); // 设定使用内存超过5M时，将产生临时文件并存储于临时目录中。
		factory.setRepository(new File(bufferPath));  // 设定存储临时文件的目录。

		ServletFileUpload upload = new ServletFileUpload(factory);
		upload.setHeaderEncoding("UTF-8");

		try {
			List items = upload.parseRequest(request);
			for (Object item1 : items) {
				FileItem item = (FileItem) item1;
				if (!item.isFormField()) {  //如果是文件域
					AttachInfo fue = new AttachInfo();  //new一个文件信息对象
					String fileName = item.getName();
					fue.setFileName(fileName);
					fue.setSize(String.valueOf(item.getSize()));
					fue.setPath(path);
					if (fileName != null) {
						String endstr = fileName.substring(fileName.lastIndexOf("."), fileName.length());
						fue.setExtName(endstr);
						fileName = DateUtil.getTimestamp() + CharUtil.getRanNumber(4) + endstr;
					} else {
						fue.setExtName("");
						fileName = DateUtil.getTimestamp() + CharUtil.getRanNumber(4);
					}
					//设置文件访问路径。。此路径并非正真的访问路径，但是这里返回一个正常访问的地址
					fue.setAccessPath(request.getContextPath() + "/Stream/" + ace.getParamname() + "/" + fileName);
					fue.setUpFileName(fileName);

					File uploadedFile;
					OutputStream os = null;
					InputStream is = null;
					try {
						uploadedFile = new File(path, fileName);
						os = new FileOutputStream(uploadedFile);
						is = item.getInputStream();
						byte buf[] = new byte[1024];// 可以修改 1024 以提高读取速度
						int length;
						while ((length = is.read(buf)) > 0) {
							os.write(buf, 0, length);
						}
						os.flush();
						log.debug("File Upload Success!");
						//是否添加到数据库
						if (isRecordBd) {
							try {
								String fileid = DateUtil.getTimestamp() + CharUtil.getRanNumber(2);
								fue.setFileId(fileid);
								AttachDao attachDao = (AttachDao) SpringContextHolder.getBean("attachDao");
								attachDao.insertAttachInfo(fue);
								returnlist.add(fue);  //添加到列表中
							} catch (Exception e) {
								log.error("文件上传信息存入数据库失败!", e);
							}
						}
						returnlist.add(fue);  //添加到列表中
					} catch (Exception e) {
						log.debug("文件上传出现问题" + e.getMessage());
						throw e;
					} finally {
						if (os != null) {
							os.close();
						}
						if (is != null) {
							is.close();
						}
					}
				}
			}

		} catch (FileUploadException e) {
			log.debug("文件上传终止--信息："+e.getMessage());
			throw e;
		}
		return returnlist;
	}

}
